/*
 * @(#)org.example 2020/3/22/0022
 *
 * Copy Right@ 人人译视界
 */


package org.example;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import org.example.register.IRegisterCenter;
import org.example.service.ServiceImpl;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

/**
 * <pre>
 * @author tuwei
 *
 * @version 0.9
 *
 * 修改版本: 0.9
 * 修改日期: 2020/3/22/0022
 * 修改人 :  tuwei
 * 修改说明: 初步完成
 * 复审人 ：
 * </pre>
 */
public class NettyRpcServer {
	private IRegisterCenter registerCenter;
	private String serviceAddress;
	private Map<String, Object> handlerMap = new HashMap<>(16);

	public NettyRpcServer(IRegisterCenter registerCenter, String serviceAddress) {
		this.registerCenter = registerCenter;
		this.serviceAddress = serviceAddress;
	}

	/**
	 * 发布服务
	 */
	public void publisher() {
		for (String serviceName : handlerMap.keySet()) {
			registerCenter.registry(serviceName, serviceAddress);
		}
		try {
			EventLoopGroup bossGroup = new NioEventLoopGroup();
			EventLoopGroup workerGroup = new NioEventLoopGroup();
			//启动netty服务
			ServerBootstrap bootstrap = new ServerBootstrap();
			bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class);
			bootstrap.childHandler(new ChannelInitializer<Channel>() {
				@Override
				protected void initChannel(Channel channel) throws Exception {
					ChannelPipeline channelPipeline = channel.pipeline();
					channelPipeline.addLast(new ObjectDecoder(1024 * 1024, ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())));
					channelPipeline.addLast(new ObjectEncoder());
					channelPipeline.addLast(new RpcServerHandler(handlerMap));
				}
			}).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);
			String[] addr = serviceAddress.split(":");
			String ip = addr[0];
			int port = Integer.valueOf(addr[1]);
			ChannelFuture future = bootstrap.bind(ip, port).sync();
			System.out.println("服务启动，成功。");
			future.channel().closeFuture().sync();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 子对象的实现
	 *
	 * @param services 对象实现类
	 */
	public void bind(Object... services) {
		//将实现类通过注解获取实现类的名称、实现类的实现放入map集合中。
		for (Object service : services) {
			Class clazz = service.getClass().getAnnotation(RpcAnnotation.class).value();
			handlerMap.put(clazz.getName(), service);
		}
	}
}
